package com.youbug.kefu.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.youbug.common.constant.ChatConstant;
import com.youbug.common.constant.DicTypeContent;
import com.youbug.common.exception.UploadException;
import com.youbug.kefu.dto.AgentSessionInfo;
import com.youbug.kefu.dto.SessionInfo;
import com.youbug.kefu.entity.Chat;
import com.youbug.system.entity.Dictionary;
import com.youbug.kefu.mapper.ChatMapper;
import com.youbug.kefu.service.IChatService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.youbug.system.service.ICommonService;
import com.youbug.system.service.IDictionaryService;
import com.youbug.kefu.vo.ChatVo;
import com.youbug.kefu.websocket.ChatsInfoHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 * 会话表 服务实现类
 * </p>
 *
 * @author youbug
 * @since 2023-01-07
 */
@Service
public class ChatServiceImpl extends ServiceImpl<ChatMapper, Chat> implements IChatService {

    @Autowired
    private IDictionaryService dictionaryService;

    @Autowired
    private ICommonService commonService;

    @Override
    public IPage<Chat> getChatPage(ChatVo chatVo) {

        Page<Chat> page = new Page<>();

        page.setCurrent(chatVo.getCurrentPage());

        page.setSize(chatVo.getPageSize());

        QueryWrapper<Chat> wrapper = new QueryWrapper<>();

        if(!ObjectUtils.isEmpty(chatVo.getStartTime())){

            wrapper.gt("create_time", chatVo.getStartTime());
        }

        if(!ObjectUtils.isEmpty(chatVo.getEndTime())){

            wrapper.lt("create_time", chatVo.getEndTime());
        }

        if(!ObjectUtils.isEmpty(chatVo.getAgentName())){

            wrapper.like("agent_name", chatVo.getAgentName());
        }

        wrapper.orderByDesc("create_time");

        Page<Chat> result = this.page(page, wrapper);

        return result;
    }

    @Override
    public boolean closeChat(Chat chat) {

        AgentSessionInfo agentSessionInfo = ChatsInfoHolder.agentSessionInfoMap.get(chat.getAgentId());
        agentSessionInfo.getHoldChats().remove(chat.getId());

        SessionInfo sessionInfo = ChatsInfoHolder.clientSessionInfoMap.get(chat.getClientId());
        sessionInfo.setHoldChat(null);

        QueryWrapper<Chat> wrapper = new QueryWrapper<>();
        wrapper.eq("id", chat.getId());
        wrapper.isNull("end_time");
        
        Chat chatTemp = new Chat();
        chatTemp.setState(ChatConstant.CHAT_STATE_CLOSED);
        chatTemp.setEndTime(LocalDateTime.now());

        return this.update(chatTemp, wrapper);
    }

    @Override
    public IPage<Chat> getChatPageForClient(ChatVo chatVo) {

        Page<Chat> page = new Page<>();

        page.setCurrent(chatVo.getCurrentPage());

        page.setSize(chatVo.getPageSize());

        QueryWrapper<Chat> wrapper = new QueryWrapper<>();

        if(!ObjectUtils.isEmpty(chatVo.getClientId())){

            wrapper.eq("client_id", chatVo.getClientId());
        }

        wrapper.orderByDesc("create_time");

        Page<Chat> result = this.page(page, wrapper);

        return result;
    }

    @Override
    public String download(ChatVo chatVo) {

        QueryWrapper<Chat> wrapper = new QueryWrapper<>();

        if(!ObjectUtils.isEmpty(chatVo.getStartTime())){

            wrapper.gt("create_time", chatVo.getStartTime());
        }

        if(!ObjectUtils.isEmpty(chatVo.getEndTime())){

            wrapper.lt("create_time", chatVo.getEndTime());
        }

        if(!ObjectUtils.isEmpty(chatVo.getAgentName())){

            wrapper.like("agent_name", chatVo.getAgentName());
        }

        wrapper.orderByDesc("create_time");

        List<Chat> list = this.list(wrapper);

        String subFileName = "chat/"+ System.currentTimeMillis() + "chat.xlsx";
        Dictionary localSource = dictionaryService.getOneByTypeAndCode(DicTypeContent.SYS_CONFIG, "excelExport");

        String rootFilePath = localSource.getValue()  + subFileName;

        File file = new File(rootFilePath);
        if(!file.getParentFile().exists()){
            boolean mkdirs = file.getParentFile().mkdirs();
        }
        EasyExcel.write(file, Chat.class).sheet("会话详情信息")
                .doWrite(() -> {
                    // 分页查询数据
                    return list;
                });
        Dictionary excelSource = dictionaryService.getOneByTypeAndCode(DicTypeContent.SYS_CONFIG, "excelSource");
        String fileUrl = excelSource.getValue() + subFileName;
        return fileUrl;
    }

    @Override
    public String saveAndReverseRecord(MultipartFile file) {

        String originalFilename = file.getOriginalFilename();

        if(!StringUtils.hasText(originalFilename)){
            throw  new UploadException("获取文件名失败");
        }
        String extendName = originalFilename.substring(originalFilename.indexOf("."));

        String uuid = UUID.randomUUID().toString();

        String fileName = uuid + extendName;

        String reverseFileName = uuid+ "-reverse"+extendName;

        File localFile = commonService.saveLocalFile(ChatConstant.MSG_TYPE_AUDIO, fileName, file);

        String absolutePath = localFile.getAbsolutePath();

        String reveredPath = absolutePath.replace(fileName, reverseFileName);

        try {
            String cmd = "ffmpeg.exe -i " +absolutePath+" -af areverse -preset superfast " + reveredPath;
            // 执行FFmpeg命令
            Process process = Runtime.getRuntime().exec(cmd);
            // 等待FFmpeg命令执行完毕
            int exitCode = process.waitFor();
            if (exitCode == 0) {
                System.out.println("FFmpeg命令执行成功！");
            } else {
                System.out.println("FFmpeg命令执行失败！");
            }
        } catch (IOException | InterruptedException e) {

            e.printStackTrace();
        }
        Dictionary netFileSource = dictionaryService.getOneByTypeAndCode(DicTypeContent.SYS_CONFIG, "netFileSource");

        String fileUrl = netFileSource.getValue() + ChatConstant.MSG_TYPE_AUDIO + "/" + reverseFileName;

        return fileUrl;
    }
}
